home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume12 / ln03-plot < prev    next >
Encoding:
Internet Message Format  |  1987-10-25  |  28.9 KB

  1. Subject:  v12i045:  New version of LN03 plot(3) package
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: Nick Christopher <nwc@cunixc.columbia.edu>
  7. Posting-number: Volume 12, Issue 45
  8. Archive-name: ln03-plot
  9.  
  10. My ln03 plot routines are totally written by myself, save algorithms taken
  11. from public journals. However, the driver which I had obtained from a
  12. supposedly public domain source was, in fact AT&T software. The driver is
  13. in fact the standard driver (with a small addition of a case to handle
  14. boxes, which is by no means essential) and redly available to people with
  15. who have U*IX.  The routines can also be used without the driver by
  16. linking them directly in for people who do not have the driver available.
  17. I apologize to AT&T.
  18.     /nwc
  19.  
  20. [  It was elsie!ado who first brought it to my attention.  --r$  ]
  21.  
  22. #! /bin/sh
  23. # This is a shell archive, meaning:
  24. # 1. Remove everything above the #! /bin/sh line.
  25. # 2. Save the resulting text in a file.
  26. # 3. Execute the file with /bin/sh (not csh) to create:
  27. #    Makefile
  28. #    lno.h
  29. #    order.c
  30. #    manual.txt
  31. #    ln03.man
  32. export PATH; PATH=/bin:/usr/bin:$PATH
  33. echo shar: "extracting 'Makefile'" '(324 characters)'
  34. if test -f 'Makefile'
  35. then
  36.     echo shar: "will not over-write existing file 'Makefile'"
  37. else
  38. cat << \SHAR_EOF > 'Makefile'
  39. FILES= Makefile lno.h order.c manual.txt ln03.man
  40. OBJECTS= drive.o order.o
  41. LIBS= -lm
  42. CFLAGS= -O
  43.  
  44. all: lib ln03
  45.  
  46. lib:  order.o
  47.     ar cr libln03.a order.o
  48.  
  49. ln03: $(OBJECTS)
  50.     cc $(CFLAGS) $(OBJECTS) $(LIBS) -o ln03plot
  51.  
  52. order.o: lno.h
  53.  
  54. clean:
  55.     -rm -f *.o *~
  56.  
  57. package: $(FILES) 
  58.         shar -cv $(FILES) > package
  59. print:
  60.     lpr $(FILES)
  61. SHAR_EOF
  62. if test 324 -ne "`wc -c < 'Makefile'`"
  63. then
  64.     echo shar: "error transmitting 'Makefile'" '(should have been 324 characters)'
  65. fi
  66. fi
  67. echo shar: "extracting 'lno.h'" '(1527 characters)'
  68. if test -f 'lno.h'
  69. then
  70.     echo shar: "will not over-write existing file 'lno.h'"
  71. else
  72. cat << \SHAR_EOF > 'lno.h'
  73. /* (C) Copyright 1986 Nicholas Christopher. 
  74.  *
  75.  *                lno.h
  76.  * This .h file accompanies my code, order.c, to produce graphics on sixel 
  77.  * systems. If any modification are made to this code, while I am still 
  78.  * employed by the Columbia University Center for Computing Activities, 
  79.  * please notify me.
  80.  *
  81.  */
  82.  
  83. #include <stdio.h>
  84. #define MAXVERT 243       /* verticle axis (1455) div sixels (6)   */
  85. #define Xaxis 1185        /* horizontal pixel resolution           */
  86. #define Yaxis 1455        /* vertical pixzel resolution            */
  87. #define Xdec 5665         /* horizantal decipoint resolution       */
  88. #define Ydec 7235         /* vertical decipoint resolution         */
  89. #define abs(x) ((x>=0) ? (x) :-(x))   /* absolut value             */
  90. #define newcount() (count = 1)        /* reset pattern count       */
  91. int cx     = 0;           /* memory value of x coordinate          */
  92. int cy     = 0;           /* memory value of y coordinate          */
  93. float xscale = 1.0;       /* x axis scaling factor                 */
  94. float yscale = 1.0;       /* y axis scaling factor                 */
  95. int xoffset = 0;
  96. int yoffset = 0;
  97. int mode   = 1;           /* flag of patern dot, solid, long, etc. */
  98. int count  = 1;           /* pattern position count, dot or space? */
  99.  
  100. struct sixel {
  101.   unsigned int pixels :6;         /* bit vector of the six pixels  */
  102.   int horiz;                      /* horiz coord in sparse matrix  */
  103.   struct sixel *next;
  104. };
  105.  
  106. struct sixel *vert[MAXVERT];      /* vert spine of sparse matrix   */
  107.  
  108. SHAR_EOF
  109. if test 1527 -ne "`wc -c < 'lno.h'`"
  110. then
  111.     echo shar: "error transmitting 'lno.h'" '(should have been 1527 characters)'
  112. fi
  113. fi
  114. echo shar: "extracting 'order.c'" '(17190 characters)'
  115. if test -f 'order.c'
  116. then
  117.     echo shar: "will not over-write existing file 'order.c'"
  118. else
  119. cat << \SHAR_EOF > 'order.c'
  120. /* 
  121.  * The following code is designed to be used in conjunction with the UNIX    *
  122.  * plot facilities, but may be used on its own to produce output to any      *
  123.  * sixels printing system.                                                   *
  124.  *                                                                           *
  125.  * If any modification are made to this code, while I am still employed by   *
  126.  * the Columbia University Center for Computing Activities, please notify    *
  127.  * me, nwc@cunixc.columbia.edu.                                              *
  128.  *                                                                           */
  129.  
  130. #include "lno.h"
  131. #include <stdio.h>
  132. #include <math.h>
  133.         
  134. openpl()
  135. /* nothing really needed here                                                */
  136. {
  137. }
  138.  
  139.  
  140. move(x,y)
  141. /* set cx,cy memory of last points, scale them, and clear pattern counter.   */
  142. int x,y;
  143. {
  144.   extern int cx,cy;
  145.  
  146.   newcount();
  147.   ln03scale(&x,&y);
  148.   cx = x;
  149.   cy = y;
  150. }
  151.  
  152.  
  153.  
  154. cont(x,y)
  155. /* scaled coordinates and then pass them to extend                           */
  156. {
  157.      ln03scale(&x,&y);
  158.      ln03extend(x,y);
  159. }
  160.  
  161.  
  162.  
  163. point(x,y)
  164. /* scale coordinates and pass them to spot                                   */
  165. {
  166.      ln03scale(&x,&y);
  167.      ln03spot(x,y);
  168. }
  169.  
  170.  
  171.  
  172. line(x1,y1,x2,y2)
  173. /* mark a starting point and then simply use continue to go to second point  */
  174. int x1,y1,x2,y2;
  175. {
  176.   
  177.   move(x1,y1);
  178.   ln03scale(&x2,&y2);
  179.   ln03extend(x2,y2);
  180. }
  181.  
  182.  
  183.  
  184. label(m)
  185. /* place ascii text or math font in graph page.  This is done by direct      *
  186.  * decipoint location addressing. The escape codes and text if placed in     *
  187.  * the output file before the sixels output.                                 */
  188. char *m;
  189. {
  190.   extern int cy,cx;                     /* coordinates to place label        */
  191.   double xx,yy,tempx,tempy;
  192.  
  193.   tempx = cx;
  194.   tempy = cy;
  195.   
  196. /*next two lines convert unscaled pixel coordinates to scaled decipoints,    *
  197.  *the unit the LN03 positions text by.                                       */
  198.  
  199.   xx =(Xdec * (tempx/Xaxis)) + 0.07 * tempx;      
  200.   yy =Ydec - (Ydec * (tempy/Yaxis) - 0.8 * tempy);
  201.  
  202. /* If a label starts in a "~" then tell the LN03 to use its math font.       *
  203.  * A non math font label can begin with a tilda, just prefix it by a space.  */
  204.  
  205.   if(*m == '~'){
  206.     printf("\033*>\033n\033[2 I\033[11h");
  207.     printf("\033[%d`\033[%dd%s",ln03round(xx),ln03round(yy),++m);
  208.   }
  209.   else printf("\017\033[2 I\033[11h\033[%d`\033[%dd%s",ln03round(xx),ln03round(yy),m);
  210.   
  211.   cx += (strlen(m)*15);
  212. }
  213.  
  214.  
  215.  
  216. arc(x,y,x1,y1,x2,y2)
  217. /* This arc generation routine is pretty bad... I do not use it for          *
  218.  * generating circles for this reason. Much of it depends on floating point  *
  219.  * which, depending on the machine may not be that accurate.                 */
  220. int x,y,x1,y1,x2,y2;
  221. {
  222.   double sqrt(),temp;
  223.   register int dx,dy,radsqr;
  224.   register int plotx,ploty,quad,rad,reps = 0;
  225.  
  226.   ln03scale(&x,&y);
  227.   ln03scale(&x1,&y1);
  228.   ln03scale(&x2,&y2);
  229.   dx = abs(x1-x);
  230.   dy = abs(y1-y);
  231.   radsqr = dx*dx + dy*dy;
  232.   temp = radsqr;
  233.   rad = sqrt(temp);
  234.   plotx = x1-x;                         /* x coord of first point in arc     */
  235.   ploty = y1-y;                         /* y  "     "   "     "    "  "      */
  236.   if(x1 > x+rad/2) quad = 1;            /* what quadrant are we in ?         */
  237.     else if(x1 > x) quad = 2;
  238.       else quad = 3;
  239.   if(y1 < y && quad == 2 ) quad = 4;    /* under horizon of y is 4 not 2     */
  240.   ln03filterP(x1,y1);
  241.   while(ln03aprox(plotx+x,x2,ploty+y,y2) != 1){ /* until final coord hit, go     */
  242.      if(quad == 2){ /* quadrants not standard, my are by the compass.        */
  243.         plotx--;    /* we are in North quadrant so inc x and calculate y     */
  244.         temp = radsqr - plotx*plotx;
  245.         ploty = ln03round(sqrt(temp));
  246.         ln03extend(plotx+x,ploty+y);
  247.         if(plotx+x < x-rad/2){
  248.           quad = 3;
  249.           reps++;
  250.           }
  251.       }
  252.          else if(quad == 3){            /* in west quad, inc y and calc x    */
  253.             ploty--;
  254.             temp = radsqr - ploty*ploty;
  255.             plotx =0-ln03round(sqrt(temp));
  256.             ln03extend(plotx+x,ploty+y);
  257.             if(plotx+x >= x-rad/2){
  258.                quad = 4;
  259.                reps++;
  260.             }
  261.          }
  262.           else if(quad == 4){           /* we are in south quad, mirror north*/
  263.               plotx++;
  264.               temp = radsqr - plotx*plotx;
  265.               ploty =0-ln03round(sqrt(temp));
  266.               ln03extend(plotx+x,ploty+y);
  267.               if(plotx+x > x+rad/2){
  268.                  quad = 1;
  269.                  reps++;
  270.               }
  271.           }
  272.              else{                      /* east quad, mirror west            */
  273.                  ploty++;
  274.                  temp = radsqr - ploty*ploty;
  275.                  plotx = ln03round(sqrt(temp));
  276.                  ln03extend(plotx+x,ploty+y);
  277.                  if(plotx+x <= x+rad/2){
  278.                     quad = 2;
  279.                     reps++;
  280.                  }
  281.               }
  282.   if(reps > 4) /* We have been around the circle more than once...oops!     */
  283.     {
  284.     fprintf(stderr,"Second point is not in arc of center and first point.\n");
  285.     fprintf(stderr,"Bad arc is %d, %d, %d, %d, %d, %d.\n",x,y,x1,y1,x2,y2);
  286.     fprintf(stderr," Converting sparse matrix built to date and exiting.\n");
  287.     ln03conv();
  288.     exit(1);
  289.     }
  290.   }
  291. }
  292.  
  293.  
  294.  
  295. circle(x,y,r)
  296. /* this generates 45 degrees of a circle, passing each point to circpoint    *
  297.  * which distributes the point to all eight 45 degree segments.              */
  298. int x,y,r;
  299. {
  300.   register int xx,yy,d;
  301.   extern int cx,cy;
  302.   extern float xscale,yscale;
  303.   int dummy = 1;
  304.  
  305.   newcount();
  306.  
  307.   ln03scale(&x,&y);
  308.   r = ln03round(r * xscale);
  309.   xx = 0;
  310.   yy = r;
  311.   d  = 3-2*r;
  312.   while( xx < yy){ 
  313.      ln03circpoint(xx,yy,x,y);
  314.      if(d < 0) d = d+4*xx+6;
  315.         else{
  316.            d = d+4*(xx-yy) + 10;
  317.            yy--;
  318.            }
  319.       xx++;
  320.   }
  321.   if(xx == yy) ln03circpoint(xx,yy,x,y);
  322.   cx = xx+x;
  323.   cy = yy+y;
  324. }
  325.  
  326.  
  327.  
  328. erase()
  329. /* Just convert what we have, and start fresh.                               */
  330. {
  331. ln03conv();
  332. }
  333.  
  334.  
  335.  
  336. linemod(s)
  337. /* set varible "mode" to reflect pattern chosen.                             */
  338. char *s;
  339. {
  340.   extern int mode;
  341.  
  342.   switch(s[0]){
  343.         case 'l':       
  344.                 mode = 4;
  345.                 break;
  346.         case 'd':       
  347.                 if(s[3] == 'd') mode = 5;
  348.                 else mode = 2;
  349.                 break;
  350.         case 's':
  351.                 if(s[5] != '\0') mode = 1;
  352.                 else mode = 3;
  353.    }
  354. }
  355.  
  356.  
  357. space(x1,y1,x2,y2)
  358. /* set a scaling factor at users request. scale is defaulted to 1            */
  359. int x1,y1,x2,y2;
  360. {
  361.   extern float xscale,yscale;
  362.   float temp;
  363.   extern int xoffset,yoffset;
  364.  
  365.   if (x1 < 0) xoffset = -x1;
  366.   if (y1 < 0) yoffset = -y1;
  367.  
  368.   temp = (float)Xaxis/(x2-x1);
  369.   xscale = floor(temp * 100.0)/100.0;
  370.   temp = (float)Xaxis/(y2-y1);
  371.   yscale = floor(temp * 100.0) / 100.0;
  372. }
  373.  
  374.  
  375. closepl()
  376. {
  377.   ln03conv();
  378. }
  379.  
  380. /*---------------------------------------------------------------------------*/
  381. /*           BEGIN SUPPORT ROUTINES                                          */
  382. /*---------------------------------------------------------------------------*/
  383.  
  384. ln03extend(x1,y1)
  385. /* Don't ask, I got this from a book, it forms a line by increment to a      *
  386.  * point in the area nearest the line. negative slopes are achived by        *
  387.  * mirroring a positive slope.                                               */
  388. register int x1,y1;
  389. {
  390.   extern   int cx,cy;
  391.   register int dx,dy,yincr1,mid,yincr2,yd,xincr1,xincr2,xd,x,y,xend,yend;
  392.   register int xx,yy;
  393.   register int neg=0;
  394.  
  395.  
  396.   dx     = abs(x1-cx);
  397.   dy     = abs(y1-cy);
  398.   yd     = 2*dy-dx;
  399.   yincr1 = 2*dy;
  400.   yincr2 = 2*(dy-dx);
  401.   xd     = 2*dx-dy;
  402.   xincr1 = 2*dx;
  403.   xincr2 = 2*(dx-dy);
  404.   if (cx > x1){                         /* set up initial variables          */
  405.     x = x1;
  406.     y = y1;
  407.     xend = cx;
  408.     yend = cy;
  409.     if(cy < y1 && cx != x1){            /* BELLS AND WISTLES negative slope  */
  410.       neg = 1;
  411.       mid = y1;
  412.       yend = cy+(2*dy);                 /*set y to its + slope equivalent    */
  413.     }
  414.   }
  415.   else
  416.   {
  417.     x = cx;
  418.     y = cy;
  419.     xend = x1;
  420.     yend = y1;
  421.     if(y1 < cy && cx != x1){            /* BELLS AND WISTLES negative slope  */
  422.       neg = 1;
  423.       mid = cy;
  424.       yend = y1+(2*dy);
  425.     }
  426.   }
  427.   ln03filterP(x,y);
  428.   xx = x;
  429.   yy = y;
  430.   if (x == xend)                        /* we have a totally verticle line.  */
  431.     while (y != yend){
  432.     if (y < yend) y++;
  433.       else y--;
  434.     ln03filterP(x,y);
  435.     }
  436.   while (x < xend){
  437.     if (yd < 0) yd += yincr1;
  438.     else{  
  439.       if (y < yend) y++;
  440.       else if (y > yend) y--;
  441.       yd += yincr2;
  442.     }
  443.     if (xd < 0) xd += xincr1;
  444.     else{
  445.       x++;
  446.       xd += xincr2;
  447.     }
  448.     if (xx != x || yy != y){
  449.     if(neg) ln03filterP(x,2*mid-y);
  450.       else ln03filterP(x,y);
  451.     xx = x;
  452.     yy = y;
  453.     }
  454.   }
  455.   cx = x1;                              /* remember last points              */
  456.   cy = y1;
  457. }
  458.  
  459.  
  460.  
  461. int ln03round(num)
  462. /* float number rounding                                                     */
  463. double num;
  464. {
  465.   int inum;
  466.   double rnum;
  467.  
  468.   inum = num;
  469.   rnum = num - inum;
  470.   return((rnum < .5)?inum:inum+1);
  471. }
  472.  
  473. int ln03power(z)
  474. /* this rountine accepts an integer 0-5 and first takes its five compliment  *
  475.  * then it returns 2 to the power of the result. exmp 3 = (5-3)^2 = 4        */
  476. int z;
  477. {
  478.   register int inc,final = 2;
  479.  
  480.   z = 5-z;
  481.   if(z ==0) final = 1;
  482.         else if(z==1) final = 2;
  483.                 else for(inc = 2;z >= inc; inc++) final *= 2;
  484.   return(final);
  485. }
  486.  
  487.  
  488.  
  489. int ln03aprox(a,b,c,d)
  490. /* check to see if a is aprox equal to b and if c is aprox equal to d        *
  491.  * this is done because I don't trust arc's floating point to generate       *
  492.  * the circumference points exactly.                                         */
  493. int a,b,c,d;
  494. {
  495.   if( a <= b+1 && a >= b-1 && c <= d+1 && c >= d-1) return(1);
  496.      else return(-1);
  497. }
  498.  
  499.  
  500.  
  501. death()
  502. /* Something, some where has created an error, or we are out of RAM,        *
  503.  * convert the graph as it stands.                                          */
  504. {
  505.   fprintf(stderr,"We have ran out of memory for sparse matrix nodes.\n");
  506.   fprintf(stderr,"  We will convert what has been done to date and leave.\n");
  507.   ln03conv();
  508.   exit(1);
  509. }
  510.  
  511.  
  512. ln03spot(x,y)
  513. /* place a point given by coordinates in sparse matrix.                      */
  514. int x,y;
  515. {
  516.   extern struct sixel *vert[MAXVERT];   /* this is the plotting grid         */
  517.   struct sixel *temp,*mark,*malloc();
  518.   extern int cy,cx;            
  519.   register int Vval;        /* verticle coordinate to the nearest sixel      */
  520.   register int Svval;       /* verticle coordinate, pixel remainder of sixels*/
  521.  
  522.   if(x >= 0 && x <= Xaxis && y >= 0 && y <= Yaxis){
  523.      cy = y; cx = x;      
  524.      Vval =(Yaxis-(y-2))/6;             /* div 6 to obtain sixels            */
  525.      Svval = y%6;                       /* modulo to obtain pixels remainder */
  526.      if(vert[Vval] == NULL){            /* this row is new, start it         */
  527.         if((temp = malloc(sizeof(struct sixel)))==NULL) death();
  528.         temp->pixels = 0|(ln03power(Svval));/* calc sixels' pixel value          */
  529.         temp->horiz = x;
  530.         temp->next = NULL;        
  531.         vert[Vval] = temp;
  532.         }
  533.      else{                              /* row already has member(s)         */
  534.           mark = vert[Vval];            /* set a marker to move along list   */
  535.           while(mark->next != NULL && mark->horiz < x) mark = mark->next;
  536.  
  537. /* we are now a) at row's end, b) an equal horiz,                            *
  538.  * c) a greater horiz.                                                       */
  539.  
  540.           if(mark->next == NULL && mark->horiz < x ){ 
  541.  
  542. /* time to add a node because horiz is too big and no next node.             */
  543.  
  544.              if((temp = malloc(sizeof(struct sixel)))==NULL) death();
  545.              temp->pixels = 0|(ln03power(Svval));
  546.              temp->horiz = x;
  547.              temp->next = NULL;         /* Better safe......                 */
  548.              mark->next = temp;         /* Add new node to vert structure.   */
  549.              }
  550.              else if(mark->horiz == x) mark->pixels |= ln03power(Svval);
  551.  
  552.   /* just modify this node                                                   */
  553.  
  554.                   else if(mark->horiz > x){
  555.  
  556.   /* insert new node between two present cause we have passed its spot       */
  557.  
  558.                       if((temp = malloc(sizeof(struct sixel)))==NULL) death();
  559.                         temp->pixels = mark->pixels;
  560.                         temp->horiz = mark->horiz;
  561.                         temp->next = mark->next;
  562.                         mark->pixels = 0|(ln03power(Svval));
  563.                         mark->horiz = x;
  564.                         mark->next = temp;
  565.                       }
  566.           }
  567.     }
  568. }
  569.  
  570.  
  571. ln03conv()
  572. /* This routine coverts a sparce matrix to LN03 format of sixels. The        * 
  573.  * size of the output is minimized by using the LN03's repeat format:        *
  574.  * !10? performs ? (a space) 10 times.                                       */
  575. {
  576. register int count,rep;
  577. register int Hplace;                    /* horizontal displacement           */
  578. register int lastc = 0;                 /* sixel pixel pattern holder        */
  579. int x;
  580. struct sixel *temp;
  581. extern struct sixel *vert[MAXVERT];     /* sparse matrix of sixels           */
  582.  
  583.                                         /* ESC codes to get ln03 sixels mode */
  584. printf("\033[2 I\033[1`\033[1d\033P000;0000;000q\"1;1"); 
  585. for(count = 0; count < MAXVERT; count++)
  586.   if(vert[count] == NULL) printf("?-");   /* LF for a blank row          */
  587.     else{
  588.       temp = vert[count];
  589.       if(temp->horiz>0) printf("!%d?",temp->horiz-1);/*tab to 1st char   */
  590.       printf("%c",temp->pixels+63);
  591.       Hplace = temp->horiz;
  592.       lastc = temp->pixels;
  593.       rep = 0;  
  594.       while(temp->next != NULL){
  595.            temp = temp->next;           /* move one node horizontally        */
  596.            if(temp->horiz == Hplace+1 && temp->pixels == lastc){
  597.                rep++;
  598.                Hplace++;
  599.                }
  600.              else{
  601.                 if(rep > 0) printf("!%d%c",rep,lastc+63);
  602.                 if(temp->horiz != Hplace+1 && temp->horiz <= Xaxis)
  603.                    printf("!%d?",temp->horiz - Hplace - 1);
  604.                 printf("%c",temp->pixels+63);
  605.                 Hplace = temp->horiz;
  606.                 lastc = temp->pixels;
  607.                 rep = 0;
  608.                 }
  609.            }    
  610.       if(rep > 0) printf("!%d%c-",rep,lastc+63);
  611.         else printf("-");
  612.     }
  613. printf("\033\\");                    /* Tell ln03 we are done with sixels */
  614.  
  615. for(x = 0; x < MAXVERT; x++)
  616.   vert[x] = (struct sixel *)NULL;
  617.  
  618. }
  619.  
  620.  
  621. box(x0,y0,x1,y1)
  622. /* box drawing routine                                                       */
  623. int x0,y0,x1,y1;
  624. {
  625.      int xhold,yhold;
  626.      
  627.      xhold = x0;
  628.      yhold = y0;
  629.      
  630.      ln03scale(&x0,&y0);
  631.      ln03scale(&x1,&y1);
  632.      
  633.      move(xhold,yhold);
  634.      ln03extend(x1,y0);
  635.      ln03extend(x1,y1);
  636.  
  637.      move(xhold,yhold);
  638.      ln03extend(x0,y1);
  639.      ln03extend(x1,y1);
  640. }
  641.  
  642.  
  643.  
  644. ln03circpoint(xx,yy,x,y)
  645. /* circle() only calculates 45 degrees of a circle, this distributes the     *
  646.  * coordinates given into an entire circle. The decrementing of count is so  *
  647.  * that the position in a pattern, i.e. point or space in "dot dash" is      *
  648.  * not lost.                                                                 */
  649.  
  650. int xx,yy,x,y;
  651. {
  652.   extern int cx,cy,count;
  653.  
  654.   ln03filterP(xx+x,yy+y);
  655.   count--;
  656.   ln03filterP(yy+x,xx+y);
  657.   count--;
  658.   ln03filterP(yy+x,-xx+y);
  659.   count--;
  660.   ln03filterP(xx+x,-yy+y);
  661.   count--;
  662.   ln03filterP(-xx+x,-yy+y);
  663.   count--;
  664.   ln03filterP(-yy+x,-xx+y);
  665.   count--;
  666.   ln03filterP(-yy+x,xx+y);
  667.   count--;
  668.   ln03filterP(-xx+x,yy+y);
  669. }
  670.  
  671.  
  672. ln03filterP(x,y)
  673. /* filter() acts as a middle man between a caller and spot(), i.e. if our    *
  674.  * position in the line pattern (example: dotted line) is a blank space      *
  675.  * then spot should not be called.                                           */
  676. int x,y;
  677. {
  678.   extern int mode,count;
  679.  
  680.   switch(mode){
  681.     case 1: ln03spot(x,y);                                /* solid line      */
  682.                 break;
  683.     case 2: if(count <= 3 ) ln03spot(x,y);                /* dotted line     */
  684.             if(count == 6) count = 0;
  685.                 break;
  686.     case 3: if(count <= 6 ) ln03spot(x,y);                /* short dash      */
  687.             if(count == 9) count =0;    
  688.                 break;
  689.     case 4: if(count <= 9 ) ln03spot(x,y);                /* long dash       */
  690.             if(count == 12) count =0;
  691.                 break;
  692.                                                           /* dot dash        */
  693.     case 5: if((count <= 6)||((count ==11)||(count==12))) ln03spot(x,y);
  694.             if(count == 17) count = 0;
  695.                 break;
  696.   }
  697.   count++;                              /* increment pattern position.       */
  698. }
  699.  
  700. ln03scale(x,y)
  701. int *x,*y;
  702. {
  703.      extern float xscale,yscale;
  704.      extern int xoffset,yoffset;
  705.      int tempx,tempy;
  706.  
  707.      
  708.      tempx = *x;
  709.      tempy = *y;
  710.  
  711.      tempx += xoffset;
  712.      tempy += yoffset;
  713.  
  714.      tempx = ln03round(tempx*xscale);
  715.      tempy = ln03round(tempy*yscale);
  716.  
  717.      *x = tempx;
  718.      *y = tempy;
  719. }
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727. SHAR_EOF
  728. if test 17190 -ne "`wc -c < 'order.c'`"
  729. then
  730.     echo shar: "error transmitting 'order.c'" '(should have been 17190 characters)'
  731. fi
  732. fi
  733. echo shar: "extracting 'manual.txt'" '(6901 characters)'
  734. if test -f 'manual.txt'
  735. then
  736.     echo shar: "will not over-write existing file 'manual.txt'"
  737. else
  738. cat << \SHAR_EOF > 'manual.txt'
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.                                   USERS GUIDE
  752.                                       FOR
  753.                                  PLOT FILTERS
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.                                   David Chang
  772.  
  773.                              Nicholas Christopher
  774.  
  775.                                  16 June 1987
  776.  
  777.  
  778.  
  779. 1. INTRODUCTION TO PLOT FILTERS
  780.  The UNIX operating system has, as one of its standard libraries, a library
  781. which produces graphics output in a device-independent manner.  This output
  782. can then be used as input for any compatible device-specific plot filter.
  783. The plot filter generates commands, that when redirected to its
  784. corresponding graphics device, will generate the desired graphics output.
  785.  
  786. The graphics library should be linked to your C program by using the -lplot
  787. compiler switch.
  788.  
  789.  
  790.  
  791. 2. COMMANDS
  792. The subroutines that are included in the standard UNIX Plot library
  793. are as follows:
  794.  
  795.    - openpl() 
  796.      Prepares the output device for taking 
  797.      commands.  It should always be called 
  798.      before calling any other plot subroutines.
  799.  
  800.    - erase() 
  801.      Reinitializes the output device. 
  802.  
  803.    - label(s) char[s]; 
  804.      Places text in the output at the current 
  805.      point. It takes a string variable or a string 
  806.      in quotes as its argument.  The argument is 
  807.      null-terminated and does not contain newlines.  
  808.      A local modification of the command allows the 
  809.      LN03 to use its technical font. To use the LN03 
  810.      technical font begin the label with a tilde 
  811.      character ("~"). A space-tilde, " ~", will 
  812.      allow a label in the regular font to begin 
  813.      with a tilde.
  814.  
  815.    - line(x1,y1,x2,y2)
  816.      Produces a line that starts at the point 
  817.      designated by the first two arguments that are 
  818.      passed to the subroutine and terminates at the 
  819.      point designated by the final two arguments.
  820.  
  821.    - circle(x,y,r) 
  822.      Produces a circle whose center is given by the 
  823.      first two arguments and whose radius is given 
  824.      by the final argument.
  825.  
  826.    - arc(x,y,x1,y1,x2,y2) 
  827.      Produces an arc whose center is determined by 
  828.      the first two arguments. The starting 
  829.      point is given by the third and fourth 
  830.      arguments and the end point is given by the 
  831.      final two arguments.  The arc is drawn 
  832.      counter-clockwise.
  833.  
  834.    - move(x,y) 
  835.      Changes the current point to the point given 
  836.      by the two arguments.
  837.  
  838.    - cont(x,y) 
  839.      Draws a point from the current point to the 
  840.      point given by the two arguments.
  841.  
  842.    - point(x,y) 
  843.      Draws a single point at the given coordinates.
  844.  
  845.    - linemod(s) char[s]; 
  846.      Changes the line style to the given style.  
  847.      the styles that are available are `dotted', 
  848.      `longdashed', `shortdashed', and `dotdashed'.
  849.  
  850.    - space(x1,y1,x2,y2) 
  851.      Changes the plot area, using the first two 
  852.      coordinates as the upper right hand corner of 
  853.      the plotting area and the final two arguments 
  854.      as the lower left hand corner of the plotting 
  855.      area.  The plot will be reduced or magnified 
  856.      to fit the device as closely as possible.
  857.  
  858.    - closepl() 
  859.      Closes the output device.  This should always 
  860.      be called at the end of your program.
  861.  
  862. There are two subroutines that have been added to the standard Plot
  863. library here at Columbia.  They are as follows:
  864.  
  865.    - box(x1,y1,x2,y2)
  866.      Draws a box using the two points that are 
  867.      passed as arguments as two corners.  This 
  868.      available on all the devices.
  869.  
  870.    - color(n) 
  871.      Changes the pen on a multicolor pen plotter 
  872.      to the pen number designated by the argument.  
  873.      This is only available on the pen plotters and 
  874.      ink-jet printer.
  875.  
  876.  
  877.  
  878.      This  graphics  package  can be used on the Hewlett-Packard 7470A, the DEC
  879.  
  880. LVP16, the DEC LN03 laser printer, and the DEC  LCP01  color  ink-jet  printer.
  881.  
  882. The HP 7470A is a two pen plotter.  The DEC LVP16 is a six pen plotter.
  883.  
  884.      Columbia has several pen plotters available at 251 Engineering Terrace and
  885.  
  886. LN03s at both the Engineering Terrace and SIA terminal room.  The  use  of  the
  887.  
  888. plotters  requires your own plotter pens, which can be obtained in the Business
  889.  
  890. Office, and your own 8.5" by 11" or 11" by 17" paper.
  891.  
  892.  
  893.  
  894. 3. SAMPLE SESSION
  895.  
  896.      Below is an example program in the language C to put  a  round  peg  in  a
  897.  
  898. square  hole.  If you are not familiar with the C language you should be warned
  899.  
  900. that it is case sensitive and so if you  plan  to  try  running  the  following
  901.  
  902. program maintain the capitalization exactly.
  903.                                              /* This is a comment           */
  904. main()                                       /* Start of program            */
  905. {
  906.      openpl();                               /* Initialize plot routines    */
  907.  
  908.      move(10,10);                            /* Position cursor             */
  909.      label("Demo.");                         /* Text starts at cursor       */
  910.  
  911.      box(100,100,500,500);                   /* Draw a square hole          */
  912.      circle(300,300,200);                    /* Put the round peg in        */
  913.  
  914.      move(10,600);                           /* Position cursor             */
  915.      label("Done!");                         /* Some more text              */
  916.  
  917.      closepl();                              /* Close the plot routines     */
  918. }
  919.  
  920.  
  921.  
  922.      Note  that  the only C in the entire program was "main() { }" the rest was
  923.  
  924. entirely plot commands. C code could have been present, to calculate a sin wave
  925.  
  926. by points for example, but knowledge of C is not required to use plot.
  927.  
  928.      The  above code must be compiled before it will run. Assume that the above
  929.  
  930. C program is in a file named peg.c. The command to compile C  code  which  uses
  931.  
  932. plot commands is as follows:
  933.  
  934.  
  935.     cc -o peg peg.c -lplot
  936.  
  937.  
  938.      The  above  command  generates  the  program  peg  can be run at any time,
  939.  
  940. however it is still not producing output  for  any  specific  printing  device.
  941.  
  942. Suppose  that  you  were sitting at a Tektronics terminal and wanted to see the
  943.  
  944. demonstration right on the screen. The command to give would be:
  945.  
  946.  
  947.     peg | tek
  948.  
  949.  
  950.      The above command takes the generalized output from peg and  feeds  it  to
  951.  
  952. the  program  tek  which knows how to display graphics on a Tektronics terminal
  953.  
  954. (the "|" character is called a pipe in UNIX and must be  included).    The  tek
  955.  
  956. program then produces the graphics on your screen. The command:
  957.  
  958.  
  959.     peg | ln03 | lpr -Pmuddl1
  960.  
  961.  
  962.      Would  take the same generalized output from peg feed it to ln03 a program
  963.  
  964. which creates output for the DEC LN03 printer. Then ln03  program  would  feeds
  965.  
  966. its  output to the print command, lpr -Pmuddl1, which actually prints the given
  967.  
  968. output on the LN03 printer located in 251 Engineering Terrace.
  969.  
  970.      For further documentation look in sections 1,3 and 5 of  the  UNIX  manual
  971.  
  972. under  the  title  plot. On a UNIX machine these manual sections can be read by
  973.  
  974. saying:
  975. man 1 plot
  976. man 3 plot
  977. man 5 plot
  978. SHAR_EOF
  979. if test 6901 -ne "`wc -c < 'manual.txt'`"
  980. then
  981.     echo shar: "error transmitting 'manual.txt'" '(should have been 6901 characters)'
  982. fi
  983. fi
  984. echo shar: "extracting 'ln03.man'" '(661 characters)'
  985. if test -f 'ln03.man'
  986. then
  987.     echo shar: "will not over-write existing file 'ln03.man'"
  988. else
  989. cat << \SHAR_EOF > 'ln03.man'
  990. .TH LNO3PLOT cucca
  991. .ds SI S\s-2IX\s+2\s-2ELS\s+2
  992. .SH NAME
  993. ln03plot \- convert plot(5) files to S\s-2IX\s+2\s-2ELS\s+2 format
  994. .SH SYNOPSIS
  995. .B ln03plot
  996. [
  997. .I file
  998. ]
  999. .SH DESCRIPTION
  1000. .I ln03plot
  1001. reads a
  1002. .I file
  1003. in
  1004. .IR plot (5)
  1005. format and converts it to \*(SI format on the 
  1006. standard output.  The \*(SI format is used by the LN03 printer as well as
  1007. other printers.  If no
  1008. .I file
  1009. is specified, the standard input is used.
  1010. .SH "SEE ALSO"
  1011. graph(1), ideal(1), plot(1), plot(3), plot(5), lpr(1).
  1012. .br
  1013. .SH BUGS
  1014. The LN03's printing resolution is considerably smaller than that of many
  1015. printing devices. Some input, if scaled to much larger devices may produce
  1016. poor results.
  1017. SHAR_EOF
  1018. if test 661 -ne "`wc -c < 'ln03.man'`"
  1019. then
  1020.     echo shar: "error transmitting 'ln03.man'" '(should have been 661 characters)'
  1021. fi
  1022. fi
  1023. exit 0
  1024. #    End of shell archive
  1025. -- 
  1026.         "I am the Lorvax. I speak for the machines."
  1027. ______________________________________________________________________________
  1028. nwc%cunixc@columbia, columbia!cunixc!nwc  BITNET: nwcus@cuvma 
  1029.             USENET: topaz!columbia!cunixc!nwc
  1030.